(function(host){

var ID = 0;

function InitElement(el, c){
	el.appendTo = function(parent){
		parent.appendChild(this);
		return this;
	};
	el.append = function(element){
		this.appendChild(element);
		return this;
	};
	el.attr = function(name, value){
		if(name === 'type' || name === 'id') name = '_' + name;
		name = c.prefix + '-' + name;
		if(arguments.length == 1){
			return el.getAttribute(name);
		} else if(arguments.length > 1){
			this.setAttribute(name, value);
		}
		return this;
	};
	el.ready = function(fn){
		util.isFunction(fn) && fn.call(this);
		return this;
	};
	el.rect = function(){
		return {
			left: util.toInt(el.attr('x')),
			top: util.toInt(el.attr('y')),
			width: util.toInt(el.attr('width')),
			height: util.toInt(el.attr('height'))
		}
	};
	el.snap = function(){
		this.$rect = this.rect();
		return this;
	};
	el.position = function(){
		return {
			left: util.toInt(el.attr('x')),
			top: util.toInt(el.attr('y'))
		}
	};
	el.size = function(){
		return {
			width: util.toInt(el.attr('width')),
			height: util.toInt(el.attr('height'))
		}
	};
	el.toCssText = function(){
		return util.obj2css(this.rect());
	};
	el.update = function(){
		if(!c.ignoreUpdate){
			this.style.cssText = this.toCssText();
		} else {
			this.removeAttribute('style');
		}
		return this;
	};
	el.hide = function(){
		this.addClass('hidden');
		return this;
	};
	el.show = function(){
		this.removeClass('hidden');
		return this;
	};
	el.addClass = function(name){
		this.classList.add(name);
		return this;
	};
	el.removeClass = function(name){
		this.classList.remove(name);
		return this;
	};
	el.setAttribute(c.prefix + '-id', c.id);
	el.setAttribute(c.prefix + '-type', c.type);
	el.$type = function(){ return c.type; };
	el.$id = function(){ return c.id; };
	if(util.isObject(c.attrs)){
		for(var p in c.attrs){
			el.attr(p, c.attrs[p]);
		}
	}
	if(!c.ignoreUpdate){
		el.attr('x', 0).attr('y', 0);
	}
}

function CreateUI(conf){
	var c = {};
	util.copyTo(CreateUI.defaultConfigure, c);
	util.copyTo(conf, c);
	c.id = ++ID;

	var el = document.createElement(c.name || 'div');
	InitElement(el, c)

	return el;
}

CreateUI.defaultConfigure = {
	name: 'div',
	prefix: 'ui',
	type: 'layer',
	attrs: {},
	props: {}
};

function IsUI(target){
	return target.hasAttribute(CreateUI.defaultConfigure.prefix + '-type');
}

function CreateImage(src){
	var el = ui.create({
		type: 'image'
	});
	var f;
	el.ready = function(fn){
		f = fn;
		return this;
	};
	var toCssText = el.toCssText;
	el.toCssText = function(){
		var css = toCssText.call(this);
		if(el.attr('src')){
			css += 'background-image:url(' + el.attr('src') + ');'
		}
		return css;
	};
	util.getImageData(src, function(data){
		el.attr('width', data.width);
		el.attr('height', data.height);
		el.attr('src', data.src);
		el.update();
		util.isFunction(f) && f.call(el, data);
	});
	return el;
}

function InitContainer(q){
	var el = util.$(q);
	var c = {};
	util.copyTo(CreateUI.defaultConfigure, c);
	c.type = 'container';
	c.id = ++ID;
	InitElement(el, c);

	el.addImage = function(src){
		var _ = this;
		var child = CreateImage(src).appendTo(this).ready(function(dom, data){
			util.isFunction(_.onchildready) && _.onchildready(dom, data);
		});
		child.append(CreateUI({ type: 'move', ignoreUpdate: true }));
		child.append(CreateUI({ type: 'resize', ignoreUpdate: true }));
		child.getParent = function(){ return this; }.bind(this);
		return this;
	};
	el.isUI = function(element){
		if(element === el) return false;
		return IsUI(element);
	};
	el.getChildren = function(){
		return Array.prototype.slice.call(this.children, 0);
	};
	el.getById = function(id){
		return util.$('[ui-id="' + id + '"]', 0, this);
	};

	el.blurChildren = function(dispose){
		util.$each('.active, .runtime', function(dom){
			dom.removeClass('active').removeClass('runtime');
		}, this);
		util.EACH(activeChilds, function(dom){
			dom.removeClass('active').removeClass('runtime');
		});
		dispose && activeChilds.splice(0, activeChilds.length);
		return this;
	};

	var activeChilds = [];
	var dragStartPos = null;
	var dragCommand = null;

	util.addEvent(el, 'mousedown', function(e){

		if('button' in e && e.button != 0){
			e.preventDefault();
			return;
		}

		if(e.target === el){
			this.blurChildren(true);
			return;
		}

		if(activeChilds.length){
			util.EACH(activeChilds, function(dom){
				dom.removeClass('active');
			});
			activeChilds.splice(0, activeChilds.length);
		}

		if(!el.isUI(e.target)){
			return;
		};

		e.preventDefault();
		e.stopPropagation();

		dragCommand = e.target.$type();
		switch(dragCommand){
			case 'resize':
				activeChilds.push(e.target.parentNode);
				dragStartPos = util.getSingleEventPostionINT(e);
				break;
			case 'move':
				activeChilds.push(e.target.parentNode);
				dragStartPos = util.getSingleEventPostionINT(e);
				break;
			default:
				activeChilds.push(e.target);
				console.log(dragCommand);
				dragCommand = null;
				break;
		}

		if(activeChilds.length){
			util.isFunction(this.onchildrenactive) && this.onchildrenactive(activeChilds);
			el.blurChildren();
			util.EACH(activeChilds, function(dom){
				dom.snap();
				dom.addClass('active');
				dragCommand && dom.addClass('runtime');
			});
		}
	});
	util.addEvent(document, 'mousemove', function(e){
		if(!dragCommand || !activeChilds.length){
			e.preventDefault();
			e.stopPropagation();
			return;
		}
		var pos = util.getSingleEventPostionINT(e);
		var x = pos[0] - dragStartPos[0];
		var y = pos[1] - dragStartPos[1];
		switch(dragCommand){
			case 'resize':
				util.EACH(activeChilds, function(element){
					element
						.attr('width', x + element.$rect.width)
						.attr('height', y + element.$rect.height)
						.update();
				});
				break;
			case 'move':
				util.EACH(activeChilds, function(element){
					element
						.attr('x', x + element.$rect.left)
						.attr('y', y + element.$rect.top)
						.update();
				});
				break;
		}
	});
	util.addEvent(document, 'mouseup', function(e){
		if(dragCommand){
			dragCommand = null;
			e.preventDefault();
			e.stopPropagation();

			util.EACH(activeChilds, function(element){
				element.removeClass('runtime');
			});
		}
	});

	return el;
}

host.ui = {
	create: CreateUI,
	image: CreateImage,
	init: InitContainer
};

})(window);

